/* Copyright (c) 2008, The Visigoth Software Society
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright notices,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name Visigoth Software Society, FreeCC, Sun Microsystems, Inc. 
 *       nor the names of any other contributors may be used to endorse 
 *       or promote products derived from this software without specific prior written 
 *       permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.visigoths.freecc.codegen.java;

import org.visigoths.freecc.parser.*;
import static org.visigoths.freecc.parser.FreeCCParserConstants.*;

import java.util.*;

public class TypeDeclaration extends JavaCode {
    
    public TypeDeclaration() {
        super(JJTTYPEDECLARATION);
    }
    
    public String getName() {
        for (Node n : this) {
            if ((n instanceof Token) && ((Token) n).kind == IDENTIFIER) {
                return ((Token)n).image;
            }
        }
        throw new RuntimeException("Should never get here.");
    }
    
    public String getPackageName() {
        String packageName = null;
        if (parent instanceof CompilationUnit) {
            CompilationUnit jcu = (CompilationUnit) parent; 
            packageName = jcu.getPackageName();
        }
        return packageName;
    }
    
    public String getFullName() {
        String name = getName();
        String packageName = getPackageName();
        if (packageName != null && packageName.length()>0) {
            return packageName + "." + name;
        }
        return name;
    }
    
    public TypeParameterList getTypeParameterList() {
        ListIterator<Node> iterator = iterator();
        Node n = null;
        while (!(n instanceof Token) || ((Token)n).kind != IDENTIFIER) {
            n = iterator.next();
        }
        n = iterator.next();
        if (n instanceof TypeParameterList) {
            return (TypeParameterList) n;
        }
        return null;
    }
    
    
    
    
    public ClassOrInterfaceBody getBody() {
        for (Node n : this) {
            if (n instanceof ClassOrInterfaceBody) {
                return (ClassOrInterfaceBody) n;
            }
        }
        return null;
    }
    
    public ExtendsList getExtendsList() {
        for (Node n : this) {
            if (n instanceof ExtendsList) {
                return (ExtendsList) n;
            }
        }
        return null;
    }
    
    public ImplementsList getImplementsList() {
        for (Node n : this) {
            if (n instanceof ImplementsList) {
                return (ImplementsList) n;
            }
        }
        return null;
    }
    
    public CompilationUnit getCompilationUnit() {
        Node parent = jjtGetParent();
        if (parent instanceof CompilationUnit) {
            return (CompilationUnit) parent;
        }
        return null;
    }
    
    public List<ImportDeclaration> getImportDeclarations() {
        CompilationUnit jcu = getCompilationUnit();
        if (jcu == null) {
            return new ArrayList<ImportDeclaration>();
        }
        return jcu.getImportDeclarations();
    }
    
    public void addElements(List<ClassOrInterfaceBodyDeclaration> elements) {
        Set<String> keys = new HashSet<String>();
        for (ClassOrInterfaceBodyDeclaration decl : elements) {
            String key = decl.getFullNameSignatureIfMethod();
            if (key != null) {
                keys.add(key);
            }
        }
        for (Iterator<Node> it = getBody().iterator(); it.hasNext();) {
            Node n = it.next();
            if (n instanceof ClassOrInterfaceBodyDeclaration) {
                String s = ((ClassOrInterfaceBodyDeclaration) n).getFullNameSignatureIfMethod();
                if (keys.contains(s)) {
                    it.remove();
                }
            }
        }
        getBody().prepend(elements);
    }
    
    public boolean isClass() {
        for (Node n : this) {
            if (n instanceof Token) {
                if (((Token )n).kind == CLASS) {
                    return true;
                }
            }
        }
        return false;
    }
}
